﻿using System;
using System.Threading;

namespace InDepth2Demo.Chapter15
{
    internal class MultiThread
    {
        // 前台线程与后台线程
        public static void Call()
        {
            Thread backThread = new Thread(Worker);     // 创建一个线程。 Thread类所创建的线程将默认为前台线程。
            backThread.IsBackground = true;
            backThread.Start();                         // 启动该线程。执行Worker函数的代码
            Console.WriteLine("从主线程中退出");

            // 控制台程序有两个线程，一个是运行Main函数的主线程，另一个是运行Worker函数的后台线程。
            // 一般来说，前台线程执行完毕后 CLR 会终止后台线程的运行
        }

        public static void Worker()
        {
            Thread.Sleep(6000);
            Console.WriteLine("从后台线程退出");
        }

        // 多线程编程
        private static void CallBackWorkItem(object state)
        {
            Console.WriteLine("线程池线程开始执行");
            if (state != null)
            {
                Console.WriteLine("线程池线程ID = {0} 传入的参数为 {1}", Thread.CurrentThread.ManagedThreadId, state.ToString());
            }
            else
            {
                Console.WriteLine("线程池线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            }
        }

        public static void Call2()
        {
            Console.WriteLine("主线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
            ThreadPool.QueueUserWorkItem(CallBackWorkItem);
            ThreadPool.QueueUserWorkItem(CallBackWorkItem, "work");
            Thread.Sleep(3000);
            Console.WriteLine("主线程退出");
        }

        // 协作式取消线程池线程 (System.Threading.CancellationTokenSource 对象)
        public static void Call3()
        {
            Console.WriteLine("主线程运行");
            CancellationTokenSource cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(Callback, cts.Token);          // 调用QueueUserWorkItem方法后，线程池会创建一个线程池线程，运行该方法传入的回调函数callback，并在callback函数中执行Count函数来进行计数。
            Console.WriteLine("按下回车键来取消操作");
            Console.Read();
            cts.Cancel(); // 取消请求
            Console.ReadKey();
        }
        private static void Callback(object state)
        {
            CancellationToken token = (CancellationToken)state;
            Console.WriteLine("开始计数");
            Count(token, 1000); // 开始计数
        }
        private static void Count(CancellationToken token, int countto)
        {
            for (int i = 0; i < countto; i++)
            {
                if (token.IsCancellationRequested)          // 在Count函数中检查传入的CancellationTokenSource类实例的状态。
                {
                    Console.WriteLine("计数取消");
                    return;
                }

                Console.WriteLine("计数为: " + i);
                Thread.Sleep(300);
            }

            Console.WriteLine("计数完成");
        }


    }


}
